package com.oneandseven.dajia.utils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;

/**
 * 获取本机IP地址
 *
 * @author caobin
 */
public class IpUtils {

    private static Logger logger = LoggerFactory.getLogger(IpUtils.class);

    /**
     * 判断指定ip是否在本机ip中
     *
     * @param ip
     * @return
     */
    public static boolean isContainIp(String ip) {
        List<String> ipList = getLocalIps();
        return ipList.contains(ip);
    }

    /**
     * 获取本机IP
     *
     * @return IP集合
     */
    public static List<String> getLocalIps() {
        List<String> ipList = new ArrayList<String>();
        try {
            Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip = null;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces
                        .nextElement();
                if (netInterface.isVirtual()) {
                    continue;
                }
                Enumeration addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    ip = (InetAddress) addresses.nextElement();
                    if (ip != null && ip instanceof Inet4Address
                            && !ip.isLoopbackAddress()) {
                        ipList.add(ip.getHostAddress());
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ipList;
    }

    /**
     * 获取本机IP地址
     *
     * @return
     */
    public static String getLocalIp() {
        try {
            Optional<Inet4Address> localIp4Address = getLocalIp4Address();
            if(localIp4Address.isPresent()){
                return localIp4Address.get().getHostAddress();
            }else{
                return "";
            }
        } catch (Exception e) {
            return "";
        }
    }

    public static List<Inet4Address> getLocalIp4AddressFromNetworkInterface() throws SocketException {
        List<Inet4Address> addresses = new ArrayList<>(1);
        Enumeration e = NetworkInterface.getNetworkInterfaces();
        if (e == null) {
            return addresses;
        }
        while (e.hasMoreElements()) {
            NetworkInterface n = (NetworkInterface) e.nextElement();
            if (!isValidInterface(n)) {
                continue;
            }
            Enumeration ee = n.getInetAddresses();
            while (ee.hasMoreElements()) {
                InetAddress i = (InetAddress) ee.nextElement();
                if (isValidAddress(i)) {
                    addresses.add((Inet4Address) i);
                }
            }
        }
        return addresses;
    }

    /**
     * 过滤回环网卡、点对点网卡、非活动网卡、虚拟网卡并要求网卡名字是eth或ens开头
     *
     * @param ni 网卡
     * @return 如果满足要求则true，否则false
     */
    private static boolean isValidInterface(NetworkInterface ni) throws SocketException {
        return !ni.isLoopback() && !ni.isPointToPoint() && ni.isUp() && !ni.isVirtual()
                && (ni.getName().startsWith("eth") || ni.getName().startsWith("ens") || ni.getName().startsWith("eno"));
    }

    /**
     * 判断是否是IPv4，并且内网地址并过滤回环地址.
     */
    private static boolean isValidAddress(InetAddress address) {
        return address instanceof Inet4Address && address.isSiteLocalAddress() && !address.isLoopbackAddress();
    }

    private static Optional<Inet4Address> getIpBySocket() throws SocketException {
        try (final DatagramSocket socket = new DatagramSocket()) {
            socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
            if (socket.getLocalAddress() instanceof Inet4Address) {
                return Optional.of((Inet4Address) socket.getLocalAddress());
            }
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
        return Optional.empty();
    }

    public static Optional<Inet4Address> getLocalIp4Address() throws SocketException {
        final List<Inet4Address> ipByNi = getLocalIp4AddressFromNetworkInterface();
        if (ipByNi.size() != 1) {
            final Optional<Inet4Address> ipBySocketOpt = getIpBySocket();
            if (ipBySocketOpt.isPresent()) {
                return ipBySocketOpt;
            } else {
                return ipByNi.isEmpty() ? Optional.empty() : Optional.of(ipByNi.get(0));
            }
        }
        return Optional.of(ipByNi.get(0));
    }

    /**
     * 根据url获取域名
     * @param referrer
     * @return
     */
    public static String getReferrerDomain(String referrer) {
        if (referrer != null && !referrer.isEmpty()) {
            // 使用正则表达式或其他合适的方式提取域名
            String domain;
            try {
                URI uri = new URI(referrer);
                domain = uri.getHost() + ":" + uri.getPort();
            } catch (URISyntaxException e) {
                // 如果Referer不是有效的URI，可以尝试更简单的提取域名方式
                int start = referrer.indexOf("://") + 3;
                int end = referrer.indexOf("/", start);
                domain = (end > -1) ? referrer.substring(start, end) : referrer.substring(start);
            }
            return domain;
        } else {
            return null; // 如果没有referer，则返回null
        }
    }
}

